package com.study.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * Redis 缓存操作工具类（安全泛型版本）
 */
@Component
@SuppressWarnings({"unchecked", "rawtypes"})
public class RedisCache {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    // ============================= 基础对象操作 =============================
    /**
     * 缓存基本对象（String、Integer、Boolean、自定义实体类等）
     */
    public <T> void setCacheObject(final String key, final T value) {
        redisTemplate.opsForValue().set(key, value);
    }
    /**
     * 缓存基本对象并设置过期时间
     */
    public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
    }
    /**
     * 获取缓存的基本对象
     */
    public <T> T getCacheObject(final String key) {
        Object value = redisTemplate.opsForValue().get(key);
        return value == null ? null : (T) value;
    }
    /**
     * 删除单个对象
     */
    public boolean deleteObject(final String key) {
        return Boolean.TRUE.equals(redisTemplate.delete(key));
    }
    /**
     * 删除多个对象
     */
    public long deleteObject(final Collection<String> keys) {
        Long count = redisTemplate.delete(keys);
        return count == null ? 0 : count;
    }
    /*
     * 设置缓存的有效时间（单位：秒）
     */
    public boolean expire(final String key, final long timeout) {
        return Boolean.TRUE.equals(redisTemplate.expire(key, timeout, TimeUnit.SECONDS));
    }
    /**
     * 设置缓存的有效时间（可自定义单位）
     */
    public boolean expire(final String key, final long timeout, final TimeUnit unit) {
        return Boolean.TRUE.equals(redisTemplate.expire(key, timeout, unit));
    }
    // ============================= List 操作 =============================
    /**
     * 缓存 List 数据
     */
    public <T> long setCacheList(final String key, final List<T> dataList) {
        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
        return count == null ? 0 : count;
    }
    /**
     * 获取缓存的 List 数据
     */
    public <T> List<T> getCacheList(final String key) {
        List<Object> list = redisTemplate.opsForList().range(key, 0, -1);
        if (list == null) {
            return Collections.emptyList();
        }
        List<T> result = new ArrayList<>(list.size());
        for (Object obj : list) {
            result.add((T) obj);
        }
        return result;
    }

    // ============================= Set 操作 =============================
    /**
     * 缓存 Set 数据
     */
    public <T> void setCacheSet(final String key, final Set<T> dataSet) {
        if (dataSet != null && !dataSet.isEmpty()) {
            redisTemplate.opsForSet().add(key, dataSet.toArray());
        }
    }
    /**
     * 获取缓存的 Set 数据
     */
    public <T> Set<T> getCacheSet(final String key) {
        Set<Object> set = redisTemplate.opsForSet().members(key);
        if (set == null) {
            return Collections.emptySet();
        }
        Set<T> result = new HashSet<>(set.size());
        for (Object obj : set) {
            result.add((T) obj);
        }
        return result;
    }
    // ============================= Map（Hash）操作 =============================
    /**
     * 缓存 Map 数据
     */
    public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
        if (dataMap != null && !dataMap.isEmpty()) {
            redisTemplate.opsForHash().putAll(key, dataMap);
        }
    }
    /**
     * 获取缓存的 Map 数据
     */
    public <T> Map<String, T> getCacheMap(final String key) {
        Map<Object, Object> map = redisTemplate.opsForHash().entries(key);
        Map<String, T> result = new HashMap<>();
        for (Map.Entry<Object, Object> entry : map.entrySet()) {
            result.put(String.valueOf(entry.getKey()), (T) entry.getValue());
        }
        return result;
    }
    /**
     * 向 Hash 缓存中添加单个键值对
     */
    public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
        redisTemplate.opsForHash().put(key, hKey, value);
    }
    /**
     * 获取 Hash 缓存中某个键的值
     */
    public <T> T getCacheMapValue(final String key, final String hKey) {
        Object value = redisTemplate.opsForHash().get(key, hKey);
        return value == null ? null : (T) value;
    }
    /**
     * 删除 Hash 缓存中的某个键值对
     */
    public void delCacheMapValue(final String key, final String hKey) {
        redisTemplate.opsForHash().delete(key, hKey);
    }
    /**
     * 批量获取 Hash 缓存中的多个键值
     */
    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) {
        List<Object> list = redisTemplate.opsForHash().multiGet(key, hKeys);
        if (list == null) {
            return Collections.emptyList();
        }
        List<T> result = new ArrayList<>(list.size());
        for (Object obj : list) {
            result.add((T) obj);
        }
        return result;
    }
    // ============================= 其他辅助操作 =============================
    /**
     * 根据通配符获取匹配的所有 key
     * 示例：keys("user:*") 获取所有以 user: 开头的 key
     */
    public Set<String> keys(final String pattern) {
        Set<String> keys = redisTemplate.keys(pattern);
        return keys == null ? Collections.emptySet() : keys;
    }
}
